home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 1.iso
/
toolbox
/
src
/
demos
/
OpenGL
/
space
/
sound.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-11
|
7KB
|
241 lines
/*
* Copyright (C) 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
#include <stdio.h>
#include <fcntl.h>
#ifdef SOUND
#include <audio.h>
#endif
#include <GL/gl.h>
#include "space.h"
#define CHUNK_ID 4
#define CHUNK_HEADER 8
#define FORM_CHUNK 12
#define FORM_CHUNK_DATA 4
#define COMM_CHUNK 26 /* including the header */
#define COMM_CHUNK_DATA 18
#define SSND_CHUNK 16 /* including the header */
#define SSND_CHUNK_DATA 8
typedef struct {
schar8 id[4];
uint32 size;
uint32 nchannels;
uint32 nsampframes;
uint32 sampwidth;
uint32 samprate;
} comm_chunk_t;
typedef struct {
uint32 offset;
uint32 blocksize;
uint32 file_position; /* not in AIFF file */
uint32 sample_bytes; /* not in AIFF file */
} ssnd_chunk_t;
typedef struct {
uint32 leftover_bytes;
uint32 leftover_samps;
uint32 leftover_frames;
uint32 bytes_per_buf;
uint32 samps_per_buf;
uint32 bytes_per_samp;
uint32 num_bufs;
} play_t;
#ifdef SOUND
static ALport audio_port;
static schar8 sampbuf[2*2*48000];
#endif
static sint32 fd;
static comm_chunk_t comm_data;
static ssnd_chunk_t ssnd_data;
static play_t play;
/**********************************************************************
* sound_effect() -
**********************************************************************/
void sound_effect(schar8 *soundfile)
{ uchar8 buf[32];
sint32 n,pvbuf[2];
#ifdef SOUND
ALconfig audio_port_config;
if ((fd = open(soundfile, O_RDONLY)) < 0)
exit(0);
if (read(fd, buf, CHUNK_HEADER) != CHUNK_HEADER)
exit(0) ;
comm_data.id[0] = buf[0];
comm_data.id[1] = buf[1];
comm_data.id[2] = buf[2];
comm_data.id[3] = buf[3];
comm_data.size = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7] ;
if (strncmp(comm_data.id, "FORM", 4) || comm_data.size <= 0)
exit(0);
if (read(fd, buf, FORM_CHUNK_DATA) != FORM_CHUNK_DATA)
exit(0);
/* loop on the local chunks */
while ((n = read(fd, buf, CHUNK_HEADER)) != 0) {
if (n != CHUNK_HEADER)
exit(0);
comm_data.id[0] = buf[0];
comm_data.id[1] = buf[1];
comm_data.id[2] = buf[2];
comm_data.id[3] = buf[3];
comm_data.size = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7] ;
if (!strncmp(comm_data.id, "COMM", 4)) { /* common */
if (read(fd, buf, COMM_CHUNK_DATA) != COMM_CHUNK_DATA)
exit(0);
comm_data.nchannels = (buf[0]<<8) | buf[1] ;
comm_data.nsampframes = (buf[2]<<24) | (buf[3]<<16) | (buf[4]<<8) | buf[5] ;
comm_data.sampwidth = (buf[6]<< 8) | buf[7] ;
comm_data.samprate = (buf[10]<<8) | buf[11] ;
}
else if (!strncmp(comm_data.id, "SSND", 4)) { /* sound data */
if (read(fd, buf, SSND_CHUNK_DATA) != SSND_CHUNK_DATA)
exit(0) ;
ssnd_data.offset = (buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3] ;
ssnd_data.blocksize = (buf[4]<<24) | (buf[5]<<16) | (buf[6]<<8) | buf[7] ;
ssnd_data.file_position = lseek(fd, 0, SEEK_CUR);
ssnd_data.sample_bytes = comm_data.size - 8;
lseek(fd, ssnd_data.sample_bytes, SEEK_CUR);
}
else if ((!strncmp(comm_data.id, "MARK", 4)) /* marker */
|| (!strncmp(comm_data.id, "INST", 4)) /* instrument */
|| (!strncmp(comm_data.id, "APPL", 4)) /* appl specific */
|| (!strncmp(comm_data.id, "MIDI", 4)) /* midi data */
|| (!strncmp(comm_data.id, "AESD", 4)) /* audio rec */
|| (!strncmp(comm_data.id, "COMT", 4)) /* comments */
|| (!strncmp(comm_data.id, "NAME", 4)) /* text */
|| (!strncmp(comm_data.id, "AUTH", 4)) /* text */
|| (!strncmp(comm_data.id, "(c) ", 4)) /* text */
|| (!strncmp(comm_data.id, "ANNO", 4))) /* text */ {
lseek(fd, comm_data.size, SEEK_CUR);
}
else exit(0) ;
}
/* set output sample rate */
pvbuf[0] = AL_OUTPUT_RATE;
pvbuf[1] = comm_data.samprate;
ALsetparams(AL_DEFAULT_DEVICE, pvbuf, 2);
/* configure and open audio port */
audio_port_config = ALnewconfig();
ALsetwidth(audio_port_config, comm_data.sampwidth>>3);
ALsetchannels(audio_port_config, comm_data.nchannels);
audio_port = ALopenport("space", "w", audio_port_config);
/* make the buffer large enough to hold 1/2 sec of audio frames */
play.bytes_per_samp = comm_data.sampwidth>>3;
play.bytes_per_buf = play.bytes_per_samp * comm_data.nchannels * comm_data.samprate / 2;
play.samps_per_buf = play.bytes_per_buf / play.bytes_per_samp;
play.leftover_bytes = ssnd_data.sample_bytes % play.bytes_per_buf;
play.leftover_samps = play.leftover_bytes / play.bytes_per_samp;
play.leftover_frames = play.leftover_samps / comm_data.nchannels;
play.num_bufs = ssnd_data.sample_bytes / play.bytes_per_buf;
play_file();
/*
for (n=400; n>0; n--)
play_sample(n) ;
*/
#endif
}
/**********************************************************************
* play_file() -
**********************************************************************/
static void play_file(void)
{ register sint32 i;
#ifdef SOUND
/* move the fileptr to the beginning of the sample data */
lseek(fd, ssnd_data.file_position, SEEK_SET);
for (i=0; i<play.num_bufs; i++) {
read(fd, sampbuf, play.bytes_per_buf);
ALwritesamps(audio_port, sampbuf, play.samps_per_buf);
}
read(fd, sampbuf, play.leftover_bytes);
ALwritesamps(audio_port, sampbuf, play.leftover_samps);
while (ALgetfilled(audio_port) > 0)
sginap(1);
#endif
}
/**********************************************************************
* play_sample() -
**********************************************************************/
static void play_sample(uint32 index)
{ uint32 pos = ssnd_data.file_position + index*play.bytes_per_buf ;
#ifdef SOUND
lseek(fd, pos, SEEK_SET);
if (index < play.num_bufs) {
read(fd, sampbuf, play.bytes_per_buf);
reverse_buffer(sampbuf) ;
ALwritesamps(audio_port, sampbuf, play.samps_per_buf);
}
else {
read(fd, sampbuf, play.leftover_bytes);
ALwritesamps(audio_port, sampbuf, play.leftover_samps);
}
#endif
}
/**********************************************************************
* reverse_buffer() -
**********************************************************************/
static void reverse_buffer(uchar8 *buf)
{ register uint16 *s1, *s2, tmp ;
register uint32 i,count ;
s1 = (uint16 *)buf ;
s2 = (uint16 *) (uchar8 *) (buf + play.bytes_per_buf - 4);
count = play.bytes_per_buf >> 3 ;
for (i=0; i<count; s1++,s2--,i++) {
tmp = *s1 ;
*s1 = *s2 ;
*s2 = tmp ;
}
}